package dfw

import (
	"bufio"
	"bytes"
	"encoding/binary"
)

type NetData struct {
	Id           string
	Action, Data []byte
}
type BlockData struct {
	Data          []byte
	Index, Length int
}

func NetDataPacket(netData NetData) []byte {
	var id = append(IntToBytes(len([]byte(netData.Id))), []byte(netData.Id)...)
	var action = append(IntToBytes(len(netData.Action)), netData.Action...)
	var data = append(IntToBytes(len(netData.Data)), netData.Data...)
	return append(id, append(action, data...)...)
}
func NetDataUnPack(buffer []byte) NetData {
	id := ReadBlockData(0, buffer)
	action := ReadBlockData(id.Index+id.Length, buffer)
	data := ReadBlockData(action.Index+action.Length, buffer)
	netData := NetData{
		Id:     string(id.Data),
		Action: action.Data,
		Data:   data.Data,
	}
	return netData
}
func ReadBlockData(begin int, buffer []byte) BlockData {
	dataLength := ByteToInt(buffer[begin : begin+4])
	data := make([]byte, dataLength)
	index := begin + 4
	data = buffer[index : index+dataLength]
	blockData := BlockData{
		Data:   data,
		Index:  index,
		Length: dataLength,
	}
	return blockData
}

// Packet 封包
func Packet(netData NetData) ([]byte, error) {
	data := NetDataPacket(netData)
	// 读取消息的长度，转换成int32类型（占4个字节）
	var length = int32(len(data))
	//log.Print("packet length:", length)
	var pkg = new(bytes.Buffer)
	// 写入消息头
	err := binary.Write(pkg, binary.LittleEndian, length)
	if err != nil {
		return nil, err
	}
	// 写入消息实体
	err = binary.Write(pkg, binary.LittleEndian, data)
	if err != nil {
		return nil, err
	}
	return pkg.Bytes(), nil
}

// UnPack 解包
func UnPack(reader *bufio.Reader) (NetData, error) {
	// 读取消息的长度
	lengthByte, _ := reader.Peek(4) // 读取前4个字节的数据
	lengthBuff := bytes.NewBuffer(lengthByte)
	var length int32
	err := binary.Read(lengthBuff, binary.LittleEndian, &length)
	if err != nil {
		return NetData{}, err
	}
	//log.Print("unpack length:", length)
	// Buffered返回缓冲中现有的可读取的字节数。
	if int32(reader.Buffered()) < length+4 {
		return NetData{}, err
	}

	// 读取真正的消息数据
	pack := make([]byte, int(4+length))
	_, err = reader.Read(pack)
	if err != nil {
		return NetData{}, err
	}
	data := pack[4:]
	netData := NetDataUnPack(data)
	return netData, nil
}

// ByteToInt 字节转换成整形
func ByteToInt(n []byte) int {
	bytesBuffer := bytes.NewBuffer(n)
	var x int32
	binary.Read(bytesBuffer, binary.BigEndian, &x)
	return int(x)
}

// IntToBytes 整数转换成字节
func IntToBytes(n int) []byte {
	x := int32(n)
	bytesBuffer := bytes.NewBuffer([]byte{})
	binary.Write(bytesBuffer, binary.BigEndian, x)
	return bytesBuffer.Bytes()
}
